<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Get and Set Test</title>
  </head>
  <body>
    <script src="/sw/register.js" type="module"></script>
    <script type="module">
      import { createGet } from "/packages/fs/fs-remote/main.js";
      import { init, get } from "/packages/fs/main.js";
      import { test } from "/ok-test/main.js";
      import { createData } from "/packages/hybird-data/main.js";
      import { createUser } from "/packages/user/main.js";

      // 初始化几个重要目录
      await init("local"); // 用户的本地数据
      // 建立测试目录
      await get("local/test", { create: "dir" });

      const user1 = await createUser({ user: "test-user1" });
      const user2 = await createUser({ user: "test-user2" });

      await user1.connectAllServers();
      await user2.connectAllServers();

      // 初始化角色管理器
      const certManager1 = await user1.certManager();
      const certManager2 = await user2.certManager();

      // 授权给用户2设备权限
      const cert1 = await certManager2.issue({
        userId: user1.userId,
        role: "device",
      });
      // 授权给用户1设备权限
      const cert2 = await certManager1.issue({
        userId: user2.userId,
        role: "device",
      });

      // 测试访问其他用户内容
      await test("Test Remote Directory Observation", async () => {
        const remoteUser2 = await user1.connectUser(user2.userId);
        await remoteUser2.initRTC();

        // 访问user1的内容
        const remoteAccessor = createGet({
          remoteUser: remoteUser2,
        });

        // 访问本地目录
        const localDirectory = await get("local/test/test-obs", {
          create: "dir",
        });

        // 访问远程目录，因为是测试账户，所以和本地目录内容一致
        const remoteDirectory = await remoteAccessor("local/test/test-obs", {
          create: "dir",
        });

        // 创建本地测试文件
        const localFile = await localDirectory.get("test-file-1.txt", {
          create: "file",
        });

        // 获取远程文件引用
        const remoteFile = await remoteDirectory.get("test-file-1.txt");

        // 设置远程目录变化监听器
        let resolveObservation;
        const observationPromise = new Promise((resolve) => {
          resolveObservation = resolve;
        });

        let count = 0;

        const unsubscribe = await remoteDirectory.observe((event) => {
          count++;
          resolveObservation && resolveObservation(event);
          resolveObservation = null;
        });

        // 写入本地文件，触发远程观察
        await localFile.write(`Hello World! ${new Date().toLocaleString()}`);

        // 等待远程目录变化事件
        const observationEvent = await observationPromise;

        // 取消远端观察
        await unsubscribe();

        // 再次写入，是不会触发 remoteDirectory.observe 的，因为已经取消了
        await localFile.write(`Hello World! ${new Date().toLocaleString()}`);

        await new Promise((resolve) => setTimeout(resolve, 300));

        return {
          assert:
            observationEvent.path === remoteFile.path &&
            observationEvent.type === "write" &&
            count === 1,
          content: `observationEvent.path: ${observationEvent.path}`,
        };
      });

      await test("Hybrid Data Remote Sync Test", async () => {
        const remoteUser2 = await user1.connectUser(user2.userId);
        await remoteUser2.initRTC();

        // user1的远程访问器
        const remoteAccessor = createGet({
          remoteUser: remoteUser2,
        });

        // 访问本地目录
        const localDirectory = await get("local/test/test-remote-hybird", {
          create: "dir",
        });

        // 访问远程目录，因为是测试账户，所以内容与本地相同
        const remoteDirectory = await remoteAccessor(
          "local/test/test-remote-hybird"
        );

        // 创建本地混合数据实例
        const localHybridData = await createData(localDirectory);

        // 生成初始测试内容
        const initialContent =
          "Initial Content - " + Math.random().toString(32).slice(2);
        localHybridData.val = initialContent;

        // 等待数据就绪
        await localHybridData.ready();
        await new Promise((resolve) => setTimeout(resolve, 100));

        // 创建远程混合数据实例
        const remoteHybridData = await createData(remoteDirectory);

        // 验证初始同步状态
        const initialSyncCheck =
          localHybridData.val === remoteHybridData.val &&
          remoteHybridData.val === initialContent;

        if (!initialSyncCheck) {
          throw new Error(
            "Initial sync check failed: Local data does not match remote data"
          );
        }

        // 远程数据修改测试
        const remoteModification =
          "Remote Modification - " + Math.random().toString(32).slice(2);
        remoteHybridData.val = remoteModification;

        await remoteHybridData.ready();
        await new Promise((resolve) => setTimeout(resolve, 100));

        // 验证远程修改同步状态
        const remoteSyncCheck =
          localHybridData.val === remoteHybridData.val &&
          remoteHybridData.val === remoteModification;

        if (!remoteSyncCheck) {
          throw new Error(
            "Remote modification sync check failed: Local data not synced with remote changes"
          );
        }

        // 本地数据修改测试
        const localModification =
          "Local Modification - " + Math.random().toString(32).slice(2);
        localHybridData.val = localModification;

        await localHybridData.ready();
        await new Promise((resolve) => setTimeout(resolve, 100));

        // 验证本地修改同步状态
        const localSyncCheck =
          localHybridData.val === remoteHybridData.val &&
          remoteHybridData.val === localModification;

        if (!localSyncCheck) {
          throw new Error(
            "Local modification sync check failed: Remote data not synced with local changes"
          );
        }
        return {
          assert: initialSyncCheck && remoteSyncCheck && localSyncCheck,
          content: `
      Initial sync test:
      - initialSyncCheck: ${initialSyncCheck}
      - Initial content: ${initialContent}

      Remote modification test:
      - remoteSyncCheck : ${remoteSyncCheck}
      - Modified content: ${remoteModification}

      Local modification test:
      - localSyncCheck: ${localSyncCheck}
      - Modified content: ${localModification}
                `.trim(),
        };
      });

      await test("Hybrid Data Remote Sync Array Test", async () => {
        const remoteUser2 = await user1.connectUser(user2.userId);
        await remoteUser2.initRTC();

        // user1的远程访问器
        const remoteAccessor = createGet({
          remoteUser: remoteUser2,
        });

        // 访问本地目录
        const localDirectory = await get("local/test/test-remote-hybird2", {
          create: "dir",
        });

        // 访问远程目录，因为是测试账户，所以内容与本地相同
        const remoteDirectory = await remoteAccessor(
          "local/test/test-remote-hybird2"
        );

        // 创建本地混合数据实例
        const localHybridData = await createData(localDirectory);

        // 创建远程混合数据实例
        const remoteHybridData = await createData(remoteDirectory);

        const val1 = "test - " + Math.random().toString(32).slice(2);

        // 从远端对象添加数组数据
        remoteHybridData.splice(0, 100, {
          val: val1,
        });

        await new Promise((resolve) => setTimeout(resolve, 100));

        await remoteHybridData.ready(true);
        await localHybridData.ready(true);

        // 检查本地数据是否同步
        const assert1 =
          localHybridData.length === 1 && localHybridData[0].val === val1;

        return {
          assert: assert1,
          content: `
      Remote array sync test:
      - Array length check: ${localHybridData.length === 1}
      - First item value check: ${localHybridData[0].val === val1}
      - Value: ${val1}
                `.trim(),
        };
      });

      // 删除证书授权，方便下次测试
      await certManager1.delete(cert2.id);
      await certManager2.delete(cert1.id);
    </script>
  </body>
</html>
